昨天已經把程式碼稍微整理了一下,
分出兩大部分:處理器和記憶體,
以及加上 Formatter 讓 Coding Style 能夠更一致。
但在開始實作指令集之前,還有更重要的事情。
RISC-V 的整數暫存器共有 32 個,分別是 x0 - x31,
可以參考 RISC-V ISA 的 Table 25.1 表格。
浮點數的部分是 f0 - f31 ,只有在 F/D 這兩個 Extension 用到,不在這次實作範圍內。
其中比較特別的是 x0 是永遠為 0 的,可以跟其他指令搭配使用。
例如在 RISC-V ISA Table 25.2 提到:
nop # addi x0, x0, 0
jr rs # jalr x0, 0(rs)
github 頁面 Tag: ITDay7
為了 Unit Test,先抽出一個抽象介面 REGISTER_INTERFACE
,
並在 CPU class 加入一個 set_register_file
,方便 Unit Test 抽換 Mock Instance。
考量到未來加 Unit Test 的時候,要每個用到 Register File 的指令都改過一輪,
在這個時間點就做好準備是必要的。
//registerInterface.h
class REGISTER_INTERFACE
{
public:
virtual void set_value_integer(unsigned int register_index, int32_t value) = 0;
virtual int32_t get_value_integer(unsigned int register_index) = 0;
virtual void set_pc(uint32_t value) = 0;
virtual uint32_t get_pc() = 0;
};
//cpu.h
class CPU : public sc_module
{
...
void set_register_file(const std::shared_ptr<REGISTER_INTERFACE> &instance);
...
}
另外在其他實作中,常常看到寫了 Destructor 只為了 delete Instance,
為了減少猴子手滑漏寫的機率,
在設計的時候會使用 shared_ptr 讓系統自行釋放記憶體。
//cpu.h
class CPU : public sc_module
{
...
std::shared_ptr<REGISTER_INTERFACE> register_file;
};
//main.cpp
int sc_main(int argc,char** argv)
{
...
cpu.set_register_file(std::make_shared<REGISTER>());
...
}